Skip to content

feat: bug fixes, code quality, and new features for v0.7.0#30

Merged
pratyush618 merged 6 commits intomasterfrom
feat/bug-fixes-and-improvements
Mar 21, 2026
Merged

feat: bug fixes, code quality, and new features for v0.7.0#30
pratyush618 merged 6 commits intomasterfrom
feat/bug-fixes-and-improvements

Conversation

@pratyush618
Copy link
Copy Markdown
Collaborator

Summary

  • Bug fixes & code quality: Replace all eprintln! with log crate, fix queue_name="unknown" in middleware context, replace Redis KEYS * with SCAN, add TTL to Redis execution claims, use typed exceptions in _poll_once(), declare TaskWrapper async attributes as fields, fix ruff target-version
  • Async canvas: apply_async() on Signature, chain, group, chord using native aresult() and asyncio.gather
  • Circuit breaker: Sample-based half-open recovery with configurable probe count and success rate threshold
  • Batch enqueue parity: enqueue_many() now supports delay, unique_keys, metadata, expires, result_ttl (per-job and uniform) + event/middleware dispatch

Test plan

  • cargo test --workspace — 43 Rust tests pass
  • cargo check with all feature combos (default, postgres, redis, native-async)
  • uv run python -m pytest tests/python/ -v — 345 pass, 8 skipped
  • uv run ruff check py_src/ tests/ — clean
  • uv run mypy py_src/taskito/ --no-incremental — 0 errors (77 files)
  • Verify Redis SCAN behavior with real Redis instance
  • Verify Postgres circuit breaker migration on existing DB

- Replace all eprintln! with log crate macros (15 occurrences across
  taskito-python, taskito-async, and taskito-core)
- Fix queue_name="unknown" bug in middleware context for retry/DLQ/cancel
  hooks — now passes actual queue name from ResultOutcome
- Replace Redis KEYS * with SCAN cursor in reap_expired_locks (O(N) block)
- Add 24h TTL to Redis execution claims (SET NX PX) so orphaned claims
  from dead workers auto-expire
- Use typed exceptions in JobResult._poll_once(): TaskCancelledError,
  MaxRetriesExceededError, TaskFailedError, SerializationError instead
  of generic RuntimeError
- Add TaskFailedError to exception hierarchy
- Declare _taskito_is_async and _taskito_async_fn as explicit fields on
  TaskWrapper instead of dynamic monkey-patch
- Fix ruff target-version py39 -> py310 to match requires-python
- Fix UP035 (Callable import from collections.abc) and B905 (zip strict)
  lint warnings surfaced by the target-version change
- Add apply_async() to Signature, chain, group, and chord canvas classes
- chain.apply_async() uses aresult() for truly async step-by-step execution
- group.apply_async() uses asyncio.gather for concurrent wave execution
- chord.apply_async() awaits all group results then enqueues callback
- Expose PyResultSender in __init__.py with clean fallback when
  native-async feature is not compiled in
- Update aresult() docstring to reflect typed exceptions
Replace the naive single-probe half-open strategy with a sample-based
approach: allow N probes (default 5), track success/failure counts, and
close only when the success rate meets the threshold (default 80%).

New config options on circuit_breaker dict:
- half_open_probes: number of probe requests in HalfOpen (default 5)
- half_open_success_rate: required success rate to close (default 0.8)

Behavior:
- allow() permits up to max_probes concurrent probes in HalfOpen
- record_success() closes circuit when sample meets success threshold
- record_failure() immediately re-opens if threshold becomes impossible
- Timeout: if probes don't complete within cooldown period, re-opens

Schema changes: 5 new columns on circuit_breakers table with backward-
compatible defaults. Redis uses serde(default) for JSON compatibility.
Add per-job optional parameters to enqueue_batch/enqueue_many that
were previously only available on single enqueue:
- delay_seconds_list / delay: per-job or uniform delay
- unique_keys: per-job deduplication keys
- metadata_list / metadata: per-job or uniform metadata JSON
- expires_list / expires: per-job or uniform expiry
- result_ttl_list / result_ttl: per-job or uniform result TTL

Also adds JOB_ENQUEUED event emission and on_enqueue middleware hook
dispatch to enqueue_many, matching the single enqueue behavior.
- Add 0.7.0 changelog entry with all features, fixes, and internals
- Update result.md: document typed exceptions (TaskFailedError,
  MaxRetriesExceededError, TaskCancelledError, SerializationError)
- Update canvas.md: add apply_async() docs for Signature, chain,
  group, and chord
- Update queue.md: add new enqueue_many() parameters (delay,
  unique_keys, metadata, expires, result_ttl with per-job variants)
- Update circuit-breakers.md: document sample-based half-open recovery
  with half_open_probes and half_open_success_rate parameters
@pratyush618 pratyush618 merged commit 982823b into master Mar 21, 2026
10 checks passed
@pratyush618 pratyush618 deleted the feat/bug-fixes-and-improvements branch March 31, 2026 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant